package bingo.codeweaver.core.strategy;

import net.bingosoft.common.util.StringHelper;

import org.springframework.util.Assert;

/**
 * Mar 7, 2009 12:50:23 PM DefaultNamingStrategy.java
 * Author:yangdongyu(yangdy@bingosoft.net)
 * ReadMe:
 * ChangeLog:
 */
public class DefaultNamingStrategy implements NamingStrategy{

	public String toPropertyName(String columnName) {
		return removeUnderscores(columnName,true);
	}

	public String toClassName(String tableName) {
		return removeUnderscores(tableName,false);
	}

	public String toTableName(String className) {
		return addUnderscores(className,false);
	}

	public String toColumnName(String propertyName) {
		return addUnderscores(propertyName,false);
	}


	/**
	 * 
	 * @param name
	 * @param lowerCase
	 * @return
	 */
	protected String addUnderscores(String name,boolean lowerCase) {
		StringBuffer buf = new StringBuffer( name.substring(name.lastIndexOf('.')+1) );
		for (int i=1; i<buf.length()-1; i++) {
			if (
					Character.isLowerCase( buf.charAt(i-1) ) &&
					Character.isUpperCase( buf.charAt(i) ) &&
					Character.isLowerCase( buf.charAt(i+1) )
			) {
				buf.insert(i++, '_');
			}
		}

		return lowerCase ? buf.toString().toLowerCase() : buf.toString().toUpperCase();
	}
	/**
	 * 清除字符串的下划线
	 * @param context
	 * @param firstCharLowerCase
	 * @return
	 */
	protected String removeUnderscores(String context,boolean firstCharLowerCase){
		Assert.isTrue(StringHelper.isNotEmpty(context), "columnName can not be empty or null");

		String result = context;
		String []nameFragments = context.split("_+");
		if(nameFragments.length > 1){
			boolean isFirstWord = true;
			StringBuffer sb = new StringBuffer(context.length());
			for(int i = 0 ; i < nameFragments.length;i++){
				if(!"".equals(nameFragments[i])){
					String fragment = nameFragments[i];
					if(fragment.length() == 1){
						sb.append(fragment.toUpperCase());
					}else if(fragment.length()>1){
						sb.append(isFirstWord && firstCharLowerCase ? Character.toLowerCase(fragment.charAt(0)):Character.toUpperCase(fragment.charAt(0)));
						sb.append(fragment.substring(1).toLowerCase());
					}else{
						sb.append(Character.toLowerCase(fragment.charAt(0)));
					}
					isFirstWord = false;
				}
			}
			result = sb.toString();
		}else{
			result = (firstCharLowerCase ? Character.toLowerCase(result.charAt(0)):Character.toUpperCase(result.charAt(0))) + result.substring(1).toLowerCase();
		}
		return result;
	}

}
